﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Resources;
using System.Xml;

namespace blackhouse.Translator.Business.GlobalResources {
    public class ResxTranslatorResource : ITranslatorResource {

        #region Fields

        private string directory;
        private string resourceName;
        private Dictionary<CultureInfo, Dictionary<string, ResxLine>> resourcesLines = new Dictionary<CultureInfo, Dictionary<string, ResxLine>>();
        private Dictionary<CultureInfo, FileInfo> mappedCultureToFile = new Dictionary<CultureInfo, FileInfo>();

        private CultureInfo defaultLanguage;
        private CultureInfo[] allLanguages;

        #endregion

        #region Properties

        public string Key {
            get {
                return "globresx-" + resourceName.ToLower();
            }
        }

        public string Name {
            get;
            private set;
        }

        public bool Exist {
            get;
            private set;
        }

        private Dictionary<string, ResxLine> DefaultResourceLines {
            get {
                return this.resourcesLines[this.defaultLanguage];
            }
        }

        private FileInfo DefaultResourceFile {
            get {
                return this.mappedCultureToFile[this.defaultLanguage];
            }
        }

        #endregion

        #region Constructors

        public ResxTranslatorResource(string resourcesDirectory, string resourceName, string displayName) {
            this.directory = resourcesDirectory;
            this.resourceName = resourceName;
            this.Name = displayName;

            TranslatorLanguagesManager languagesManager = new TranslatorLanguagesManager();
            this.allLanguages = languagesManager.GetSupportedLanguages();
            this.defaultLanguage = languagesManager.GetDefaultLanguage();

            this.SetResourceFile(this.defaultLanguage, resourceName + ".resx");
            this.Exist = this.mappedCultureToFile[this.defaultLanguage].Exists;
        }

        #endregion

        #region Methods

        private void SetResourceFile(CultureInfo language) {
            this.SetResourceFile(language, this.resourceName + "." + language.Name + ".resx");
        }

        private void SetResourceFile(CultureInfo language, string file) {
            if (this.mappedCultureToFile.ContainsKey(language)) return;

            FileInfo fi = new FileInfo(this.directory + file);
            this.mappedCultureToFile.Add(language, fi);

            Dictionary<string, ResxLine> lines = new Dictionary<string, ResxLine>();
            if (fi.Exists) {
                using (FileStream fs = fi.OpenRead()) {
                    XmlDocument xmlResxDoc = new XmlDocument();
                    xmlResxDoc.Load(fs);
                    XmlNodeList intNodes = xmlResxDoc.SelectNodes("root/data");
                    foreach (XmlNode intNode in intNodes) {
                        ResxLine line = new ResxLine();
                        line.Key = intNode.Attributes["name"].Value;
                        foreach (XmlNode childNode in intNode.ChildNodes) {
                            switch (childNode.Name) {
                                case "value":
                                    line.Value = childNode.InnerText;
                                    break;
                                case "comment":
                                    line.Comment = childNode.InnerText;
                                    break;
                            }
                        }
                        lines.Add(line.Key, line);
                    }
                }
            }
            this.resourcesLines.Add(language, lines);
        }

        public string[] GetAllKeys() {
            return this.DefaultResourceLines.Keys.OrderBy(s => s).ToArray();
        }

        public string GetText(CultureInfo language, string key) {
            this.SetResourceFile(language);
            Dictionary<string, ResxLine> coll = this.resourcesLines[language];
            if (coll.ContainsKey(key))
                return coll[key].Value;
            else
                return String.Empty;
        }

        public string GetComment(CultureInfo language, string key) {
            this.SetResourceFile(language);
            Dictionary<string, ResxLine> coll = this.resourcesLines[language];
            if (coll.ContainsKey(key))
                return coll[key].Comment;
            else
                return String.Empty;
        }


        public IResourceEditor GetEditor(CultureInfo language) {
            this.SetResourceFile(language);
            ResxResourceEditor editor = new ResxResourceEditor(this.DefaultResourceFile, this.mappedCultureToFile[language]);
            return editor;
        }

        #endregion

    }
}
